// Unit test for buyCard()

#include "dominion.h"  
#include "dominion_helpers.h"  
#include "rngs.h"  
#include <stdio.h>  
#include <math.h>  
#include <stdlib.h>  
#include <assert.h>

#define MAX_CARD 26

int testBuyCard(int numPlayers, int * k, struct gameState *g){
    int i, j, player, topCard, card, cost, coinsBefore, coinsAfter, deckCountBefore, deckCountAfter, buyBefore, buyAfter, supplyBefore, supplyAfter;
    player = floor(Random()*numPlayers);
    if(g->handCount[player] == 0){
      for(i = 0 ; i < 5; i++){
        topCard = g->deckCount[player]-1;
        g->hand[player][i] = g->deck[player][topCard];
        g->deckCount[player]--;
        g->handCount[player]++;
      }
    }

    for(j = 0 ; j < g->handCount[player] ; j++){
      card = floor(Random() * MAX_CARD);
      g->hand[player][j] = card;
    }
    
    g->coins = 20; // make sure there are enough coins to buy any random card
    card = floor(Random() * 10);
    // make sure the card we buy is in the selected set for this game
    card = k[card];
    coinsBefore = g->coins;
    deckCountBefore = g->deckCount[player];
    buyBefore = g->numBuys;
    supplyBefore = g->supplyCount[card];
    buyCard(card, g);
    coinsAfter = g->coins;
    deckCountAfter = g->deckCount[player];
    buyAfter = g->numBuys;
    supplyAfter = g->supplyCount[card];
    // make sure the player's buys have been decremented
    if(buyAfter != (buyBefore - 1))
      return 0;
    // make sure the supply for that card is decremented
    if(supplyAfter != (supplyBefore -1))
      return 0;
    // make sure players coins are decremented buy the appropriate amount
    if(coinsAfter != (coinsBefore - getCost(card)))
      return 0;
    // make sure a card has been added to the player's deck (this fails)
    if(deckCountAfter != (deckCountBefore + 1))
      return 0;
    return 1;
}

int main(int argc, char *argv[]) {
  long seed;
  struct gameState g;
  int players, i, j, good, bad, results;
  int k[10] = {adventurer, gardens, great_hall, village, minion, mine, cutpurse, 
           baron, salvager, smithy};
  bad = 0;
  good = 0;
  printf("\nUnit Test 4 -> buyCard() :\n");
  if(argc < 2){
    printf("Usage: ./unttest4.c [random_seed]\n");
  }
  for (j = 0; j < 1000; j++) {
    for (i = 0; i < sizeof(struct gameState); i++) {
      ((char*)&g)[i] = floor(Random() * 256);
    }
    // give different seed for every test 
    seed = (long)floor(Random()*(long)argv[1]+j);       
    players = j+2;
    // comment out next 2 lines to see bug
    if(players > 4)
      players = players%3+2; // makes sure num players = 2 to 4
    initializeGame(players, k, seed, &g);

    results = testBuyCard(players, k, &g);
  if(results == 1){
  //    printf("Test Passed!\n");
      good++;
    }
    else{
  //    printf("Test Failed!\n");
      bad++;
    }
  //  printf("\n");
  }
  printf("Tests passed = %i\n", good);
  printf("Tests Failed = %i\n", bad);
  return 0;
}